<?php

namespace app\admin\controller\pt;

use app\common\controller\Backend;
use \app\admin\model\pt\Grade;
use \app\admin\model\pt\Job;
use \app\admin\model\pt\JobOffer;
use think\Db;
use think\Exception;
use think\ValidateException;
use think\exception\PDOException;
use app\common\library\pt\Config;

/**
 * 订单录入
 *
 * @icon fa fa-circle-o
 */
class Order extends Backend
{

    /**
     * Order模型对象
     * @var \app\admin\model\pt\Order
     */
    protected $model = null;

    public function _initialize()
    {
        parent::_initialize();
        $this->model = new \app\admin\model\pt\Order;

        $this->view->assign("orderSourceList", $this->model->getOrderSourceList());
        $this->view->assign("userSourceList", $this->model->getUserSourceList());
        $this->view->assign("ptOrderLevelList", $this->model->getPtOrderLevelList());
        $this->view->assign("reviewFormStatusList", $this->model->getReviewFormStatusList());
        $this->view->assign("orderStatusList", $this->model->getOrderStatusList());
        $this->view->assign("workDetailStatusList", $this->model->getWorkDetailStatusList());


    }


    /**
     * 查看
     *
     * @return string|Json
     * @throws \think\Exception
     * @throws DbException
     */
    public function index()
    {
        //设置过滤方法
        $this->request->filter(['strip_tags', 'trim']);
        if (false === $this->request->isAjax()) {
            return $this->view->fetch();
        }
        //如果发送的来源是 Selectpage，则转发到 Selectpage
        if ($this->request->request('keyField')) {
            return $this->selectpage();
        }
        [$where, $sort, $order, $offset, $limit] = $this->buildparams();
        $list = $this->model
            ->where($where)
            ->with('jobs', 'series')
            ->order($sort, $order)
            ->paginate($limit);
        $result = ['total' => $list->total(), 'rows' => $list->items()];
        return json($result);
    }


    /**
     * 添加
     *
     * @return string
     * @throws \think\Exception
     */
    public function add()
    {
        if (false === $this->request->isPost()) {
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }
        $params = $this->preExcludeFields($params);

        if ($this->dataLimit && $this->dataLimitFieldAutoFill) {
            $params[$this->dataLimitField] = $this->auth->id;
        }

        // 验证订单参数
        $this->validateOrderParams($params);

        // 检查职称级别是否为空
        if (empty($params['grade_id'])) {
            $this->error(__('请选择职称级别'));
        }

        //查询pt_series
        $grade = Grade::where('id', $params['grade_id'])->find();
        if (empty($grade)) {
            $this->error(__('职称级别不存在'));
        }

        //查询agency
        $agency = Db::name('pt_agency')->where('id', $params['agency_id'])->find();
        if (empty($agency)) {
            $this->error(__('机构不存在'));
        }

        //订单状态
        $params['order_status'] = 1;
        //生成订单流水号
        $params['order_no'] = $this->generateOrderNo();
        $params['pt_grade'] = $grade['grade_code'];
        // 生成总序号和单位总序号
        $params['serial_no'] = $this->generateSerialNo($grade['grade_code']);
        $params['agency_serial_no'] = $this->generateAgencySerialNo($agency['agency_code'], $grade['grade_code']);
        //如果合同开始时间和合同截止时间为空 param中移除该字段
        if (empty($params['contract_start_time'])) {
            unset($params['contract_start_time']);
        }
        if (empty($params['contract_end_time'])) {
            unset($params['contract_end_time']);
        }
        //$user = $this->auth->getUserInfo();
        $job_detail_conf = Config::getConfig(null, "job_details", "tabs");
        if (empty($job_detail_conf)) {
            $this->error(__('暂未配置工作细项'));
        }

        if (empty($params['leader_id'])) {
            $this->error(__('未选择组长'));
        }


        //$params['leader_name'] = $this->auth->username;
        $result = false;
        Db::startTrans();
        try {
            //更新订单信息
            $result = $this->model->allowField(true)->save($params);
            $order_id = $this->model->getLastInsID();
            //新增工作明细
            $jobs = [];
            foreach ($job_detail_conf as $workDetail) {
                $jobs[] = [
                    'order_id' => $order_id,
                    'job_code' => $workDetail[1],
                    'title' => $workDetail[0],
                    //后面提交的时候再赋值,此处为系统新增
                    //$job['creator_id'] =  $user['id']   ;
                    //$job['creator_name'] =  $user['username']   ;
                    'status' => 0,
                ];

            }
            //Job::allowField(true)->saveAll($jobs);
            $jobModel = new Job(); // 或 model('Job')
            $jobModel->allowField(true)->saveAll($jobs);
            //新增组长的工作邀请
            $jobOffers = [
                'order_id' => $order_id,
                'position' => 0, //组长职位
                'user_id' => $params['leader_id'],
                'offer_status' => 2, //已接收
            ];
            $jobOfferModel = new JobOffer();
            $jobOfferModel->allowField(true)->save($jobOffers);
            Db::commit();
        } catch (ValidateException | PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($result === false) {
            $this->error(__('No rows were inserted'));
        }
        $this->success();
    }


    /**
     * 编辑
     *
     * @param $ids
     * @return string
     * @throws DbException
     * @throws \think\Exception
     */
    public function edit($ids = null)
    {

        $row = $this->model->with('jobs')->find($ids);
        if (!$row) {
            $this->error(__('No Results were found'));
        }
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds) && !in_array($row[$this->dataLimitField], $adminIds)) {
            $this->error(__('You have no permission'));
        }
        if (false === $this->request->isPost()) {

            $this->view->assign('row', $row);
            return $this->view->fetch();
        }
        $params = $this->request->post('row/a');
        if (empty($params)) {
            $this->error(__('Parameter %s can not be empty', ''));
        }

        // 验证订单参数
        $this->validateOrderParams($params);

        // 检查职称级别是否为空
        if (empty($params['grade_id'])) {
            $this->error(__('请选择职称级别'));
        }

        //如果合同开始时间和合同截止时间为空 param中移除该字段
        if (empty($params['contract_start_time'])) {
            unset($params['contract_start_time']);
        }
        if (empty($params['contract_end_time'])) {
            unset($params['contract_end_time']);
        }
        //查询原有的order
        $order = $this->model->where('id', $row['id'])->find();
        $grade_changed = false;
        if ($order['grade_id'] != $params['grade_id']) {
            $grade_changed = true;
        }
        //检查组长是否变化
        $leader_changed = false;
        if ($order['leader_id'] != $params['leader_id']) {
            $leader_changed = true;
        }
        //查询pt_series
        $grade = Grade::where('id', $params['grade_id'])->find();
        if (empty($grade)) {
            $this->error(__('职称级别不存在'));
        }
        $params = $this->preExcludeFields($params);
        $result = false;
        Db::startTrans();
        try {


            $result = $row->allowField(true)->save($params);
            //如果职称系列发生了变化,则需要删除原有的工作明细
            if ($grade_changed) {
                $jobModel = new Job(); // 或 model('Job')
                $jobModel->where('order_id', $row['id'])->delete();
                $grade = Grade::where('id', $params['grade_id'])->with('workDetails')->find();
                if (empty($grade)) {
                    $this->error(__('职称系列不存在'));
                }
                if (empty($grade['work_details'])) {
                    $this->error(__('请先维护职称系列下的工作明细信息'));
                }
                //新增工作明细
                $job = [];
                foreach ($grade['work_details'] as $workDetail) {
                    $job[] = [
                        'order_id' => $row['id'],
                        'work_detail_id' => $workDetail['id'],
                        'title' => $workDetail['work_detail_name'],
                        //后面提交的时候再赋值,此处为系统新增
                        //$job['creator_id'] =  $user['id']   ;
                        //$job['creator_name'] =  $user['username']   ;
                        'status' => 0,
                    ];
                }
                $jobModel->allowField(true)->saveAll($job);
            }
            //如果组长发生了变化,则需要删除原有的组长的工作邀请
            if ($leader_changed) {
                $jobOfferModel = new JobOffer();
                $jobOfferModel->where('order_id', $row['id'])->where('position', 0)->delete();
                //新增组长的工作邀请
                $jobOffers = [
                    'order_id' => $row['id'],
                    'position' => 0, //组长职位
                    'user_id' => $params['leader_id'],
                    'offer_status' => 2, //已接收
                ];
                $jobOfferModel->allowField(true)->save($jobOffers);
            }

            Db::commit();
        } catch (ValidateException | PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if (false === $result) {
            $this->error(__('No rows were updated'));
        }
        $this->success();
    }

    /**
     * 删除
     *
     * @param $ids
     * @return void
     * @throws DbException
     * @throws DataNotFoundException
     * @throws ModelNotFoundException
     */
    public function del($ids = null)
    {
        if (false === $this->request->isPost()) {
            $this->error(__("Invalid parameters"));
        }
        $ids = $ids ?: $this->request->post("ids");
        if (empty($ids)) {
            $this->error(__('Parameter %s can not be empty', 'ids'));
        }
        $pk = $this->model->getPk();
        $adminIds = $this->getDataLimitAdminIds();
        if (is_array($adminIds)) {
            $this->model->where($this->dataLimitField, 'in', $adminIds);
        }
        $list = $this->model->where($pk, 'in', $ids)->select();

        $count = 0;
        Db::startTrans();
        try {
            foreach ($list as $item) {
                //检查订单状态
                if ($item['order_status'] != 1) {
                    $this->error(__('订单状态不为新增,不能删除'));
                }
                $count += $item->delete();
                //删除组长的工作邀请
                $jobOfferModel = new JobOffer();
                $jobOfferModel->where('order_id', $item['id'])->where('position', 0)->delete();
                //删除工作明细
                $jobModel = new Job();
                $jobModel->where('order_id', $item['id'])->delete();
            }
            Db::commit();
        } catch (PDOException | Exception $e) {
            Db::rollback();
            $this->error($e->getMessage());
        }
        if ($count) {
            $this->success();
        }
        $this->error(__('No rows were deleted'));
    }

    /**
     * 人员管理页面
     * @param $order_id
     * @return string
     */
    public function user_offer($order_id = null)
    {
        $jobOfferModel = new JobOffer();
        if (!$order_id) {
            $this->error('订单ID不能为空');
        }

        // 获取订单信息
        $order = $this->model->where('id', $order_id)->find();
        if (!$order) {
            $this->error('订单不存在');
        }

        // 获取现有的offer信息,查询订单下 根据position分组后,最大的create_time各个职务人员邀请
        // 使用数据库的排序保证唯一性
        $ids = $jobOfferModel
            ->where('order_id', $order_id)
            ->group('position')
            ->field('max(id) as id') // 假设 id 越大表示越新（或结合时间）
            ->column('max(id)');

        $offers = $jobOfferModel
            ->with('user')
            ->where('id', 'in', $ids)
            ->select();
        $result = [];
        //获取下拉的人员列表
        $positions = $jobOfferModel->getJobOfferPositionList();
        if (empty($offers)) {//说明该订单下没有人员分配
            foreach ($positions as $key => $position) {
                $result[] = [
                    'position' => $key,
                    'position_text' => $position,
                    'user_id' => '',
                    'user_name' => '',
                    'offer_status' => 1,
                    'offer_status_text' => '待处理',
                    'users' => Db::name('admin')                    // 对应 fa_admin 表
                        ->alias('a')                              // 给 admin 表起别名 a
                        ->join('auth_group_access aga', 'a.id = aga.uid')   // 使用 a.id
                        ->join('auth_group ag', 'ag.id = aga.group_id')     // 使用 ag.id
                        ->where('ag.name', $position)             // 按角色组名称过滤
                        ->where('a.status', 'normal')             // 状态为 normal
                        ->field('a.id, a.username, a.nickname, a.mobile, a.email, ag.name as group_name')
                        ->select(),
                ];
            }
        } else {
            foreach ($offers as $offer) {
                $result[] = [
                    'position' => $offer['position'],
                    'position_text' => $offer['position_text'],
                    'user_id' => $offer['user']['id'],
                    'user_name' => $offer['user']['username'],
                    'offer_status' => $offer['offer_status'],
                    'offer_status_text' => $offer['offer_status_text'],
                    'users' => Db::name('admin')                    // 对应 fa_admin 表
                        ->alias('a')                              // 给 admin 表起别名 a
                        ->join('auth_group_access aga', 'a.id = aga.uid')   // 使用 a.id
                        ->join('auth_group ag', 'ag.id = aga.group_id')     // 使用 ag.id
                        ->where('ag.name', $offer['position_text'])             // 按角色组名称过滤
                        ->where('a.status', 'normal')             // 状态为 normal
                        ->field('a.id, a.username, a.nickname, a.mobile, a.email, ag.name as group_name')
                        ->select(),
                ];
            }
        }



        $this->view->assign("jobOfferPositions", $positions);
        $this->view->assign('order', $order);
        $this->view->assign('offers', $result);

        // 如果是AJAX请求，返回JSON格式
        if ($this->request->isAjax()) {
            $this->success('', '', [
                'html' => $this->view->fetch()
            ]);
        }

        return $this->view->fetch();
    }

    /**
     * 保存人员分配
     */
    public function save_offers()
    {
        if (!$this->request->isPost()) {
            $this->error('请求方式错误');
        }

        $order_id = $this->request->post('order_id');
        $offers = $this->request->post('offers/a');

        if (!$order_id) {
            $this->error('订单ID不能为空');
        }

        if (!$offers || !is_array($offers)) {
            $this->error('人员分配信息不能为空');
        }

        Db::startTrans();
        try {
            // 删除原有的分配记录
            Db::name('pt_job_offer')->where('order_id', $order_id)->where('offer_status', 1)->delete();

            // 插入新的分配记录
            $insertData = [];
            foreach ($offers as $offer) {
                //如果状态为2 已接收 则不进行插入
                if (isset($offer['offer_status']) && $offer['offer_status'] == 2) {
                    continue;
                } else {
                    //如果user_id存在为空 则报错
                    if (!$offer['user_id']) {
                        $this->error('人员ID不能为空,请选择人员');
                    }

                    $insertData[] = [
                        'order_id' => $order_id,
                        'position' => $offer['position'],
                        'user_id' => $offer['user_id'],
                        'offer_status' => 1, //  1-进行中, 2-已完成, 3-已拒绝
                    ];
                }

            }

            if (!empty($insertData)) {
                Db::name('pt_job_offer')->insertAll($insertData);
            }

            Db::commit();
            $this->success('人员分配保存成功');
        } catch (Exception $e) {
            Db::rollback();
            $this->error('保存失败：' . $e->getMessage());
        }

    }

    /**
     * 生成订单流水号
     * 格式：年月日时分秒毫秒+5位流水号
     * 例如：202412011430251234500001
     * 
     * @return string
     */
    private function generateOrderNo()
    {
        // 获取当前时间戳（精确到毫秒）
        $microtime = microtime(true);
        $timestamp = (int) ($microtime * 1000);

        // 格式化为年月日时分秒毫秒
        $dateTime = date('YmdHis', $timestamp / 1000);
        $milliseconds = str_pad($timestamp % 1000, 3, '0', STR_PAD_LEFT);

        // 生成5位流水号（基于毫秒时间戳的后5位）
        $serialNumber = str_pad($timestamp % 100000, 5, '0', STR_PAD_LEFT);

        // 组合成完整的订单号
        $orderNo = $dateTime . $milliseconds . $serialNumber;

        // 检查订单号是否已存在，如果存在则重新生成
        $exists = \think\Db::name('pt_order')->where('order_no', $orderNo)->find();
        if ($exists) {
            // 如果存在，在流水号后加1
            $orderNo = $dateTime . $milliseconds . str_pad(($timestamp % 100000 + 1), 5, '0', STR_PAD_LEFT);
        }

        return $orderNo;
    }

    /**
     * 生成总序号
     * 格式：系列代码-4位流水号
     * 例如：M-0001, E-0002
     * 
     * @param string $seriesCode 系列代码
     * @return string
     */
    private function generateSerialNo($seriesCode)
    {
        // 查询该系列代码下的最大序号
        $maxSerialNo = \think\Db::name('pt_order')
            ->where('serial_no', 'like', $seriesCode . '-%')
            ->max('serial_no');

        $nextNumber = 1; // 默认从1开始

        if (!empty($maxSerialNo)) {
            // 解析最大序号，获取数字部分
            $parts = explode('-', $maxSerialNo);
            if (count($parts) >= 2) {
                $nextNumber = (int) $parts[1] + 1;
            }
        }

        // 生成新的序号，4位数字，不足补0
        return $seriesCode . '-' . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);
    }

    /**
     * 生成单位总序号
     * 格式：机构代码-系列代码-4位流水号
     * 例如：A001-M-0001, B002-E-0002
     * 
     * @param string $agencyCode 机构代码
     * @param string $seriesCode 系列代码
     * @return string
     */
    private function generateAgencySerialNo($agencyCode, $seriesCode)
    {
        // 查询该机构下该系列的最大序号
        $pattern = $agencyCode . '-' . $seriesCode . '-%';
        $maxAgencySerialNo = \think\Db::name('pt_order')
            ->where('agency_serial_no', 'like', $pattern)
            ->max('agency_serial_no');

        $nextNumber = 1; // 默认从1开始

        if (!empty($maxAgencySerialNo)) {
            // 解析最大序号，获取数字部分
            $parts = explode('-', $maxAgencySerialNo);
            if (count($parts) >= 3) {
                $nextNumber = (int) $parts[2] + 1;
            }
        }

        // 生成新的单位序号，4位数字，不足补0
        return $agencyCode . '-' . $seriesCode . '-' . str_pad($nextNumber, 4, '0', STR_PAD_LEFT);
    }

    /**
     * 校验身份证号码
     * 
     * @param string $idCard 身份证号码
     * @return bool
     */
    private function checkIdCard($idCard)
    {
        if (empty($idCard)) {
            return false;
        }

        // 18位身份证号码正则表达式
        $pattern = '/^[1-9]\d{5}(18|19|20)\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx]$/';

        if (!preg_match($pattern, $idCard)) {
            return false;
        }

        // 校验码验证
        $weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
        $checkCodes = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];

        $sum = 0;
        for ($i = 0; $i < 17; $i++) {
            $sum += intval($idCard[$i]) * $weights[$i];
        }

        $checkCode = $checkCodes[$sum % 11];

        return strtoupper($idCard[17]) === $checkCode;
    }

    /**
     * 验证订单参数
     * 
     * @param array $params 订单参数
     * @return void
     * @throws \think\exception\HttpException
     */
    private function validateOrderParams(&$params)
    {
        // 检查身份证是否存在
        if (empty($params['id_card'])) {
            $this->error(__('请输入身份证号'));
        }

        // 检查身份证是否合法
        if (!$this->checkIdCard($params['id_card'])) {
            $this->error(__('身份证不合法'));
        }

        // 检查省市区
        // if (empty($params['province_id']) || empty($params['city_id']) || empty($params['district_id'])) {
        //     $this->error(__('请选择省市区'));
        // }

        // 检查单位
        // if (empty($params['company'])) {
        //     $this->error(__('请输入单位'));
        // }

        // 检查用户名称
        if (empty($params['user_name'])) {
            $this->error(__('请输入用户名称'));
        }

        // 检查年份
        if (empty($params['year'])) {
            $this->error(__('请输入年份'));
        }

        // 检查合同期限
        // if (empty($params['contract_term'])) {
        //     $this->error(__('请输入合同期限'));
        // }

        // 检查合同开始时间
        // if (empty($params['contract_start_time'])) {
        //     $this->error(__('请输入合同开始时间'));
        // }

        // 检查合同截止时间
        // if (empty($params['contract_end_time'])) {
        //     $this->error(__('请输入合同截止时间'));
        // }

        // 检查合同费用
        // if (empty($params['contract_fee'])) {
        //     $this->error(__('请输入合同费用'));
        // }

        // 检查机构
        if (empty($params['agency_id'])) {
            unset($params['agency_id']);
            unset($params['agency_name']);
        }

        // 检查系列
        if (empty($params['series_id'])) {
            unset($params['series_id']);
            unset($params['series_name']);
        }

        // 检查专业
        if (empty($params['major_id'])) {
            unset($params['major_id']);
            unset($params['major_name']);
        }

        // 检查电话
        // if (empty($params['utel'])) {
        //     $this->error(__('请输入电话'));
        // }

        // 检查手机号有效性
        if (!empty($params['utel']) && !preg_match('/^1[3-9]\d{9}$/', $params['utel'])) {
            $this->error(__('请输入正确的手机号'));
        }
    }

    /**
     * 默认生成的控制器所继承的父类中有index/add/edit/del/multi五个基础方法、destroy/restore/recyclebin三个回收站方法
     * 因此在当前控制器中可不用编写增删改查的代码,除非需要自己控制这部分逻辑
     * 需要将中application/admin/library/traits/Backend.php对应的方法复制到当前控制器,然后进行修改
     */


}
